package org.zwy.gradetrack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zwy.gradetrack.entity.OperationLog;
import org.zwy.gradetrack.entity.User;
import org.zwy.gradetrack.mapper.OperationLogMapper;
import org.zwy.gradetrack.service.OperationLogService;
import org.zwy.gradetrack.service.UserService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 操作日志服务实现类
 */
@Service
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog> implements OperationLogService {

    @Autowired
    private UserService userService;

    @Override
    public Page<OperationLog> pageLogs(Page<OperationLog> page, String operationModule, String operationType, LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (operationModule != null && !operationModule.isEmpty()) {
            wrapper.like(OperationLog::getOperationModule, operationModule);
        }
        if (operationType != null && !operationType.isEmpty()) {
            wrapper.eq(OperationLog::getOperationType, operationType);
        }
        if (startTime != null) {
            wrapper.ge(OperationLog::getOperationTime, startTime);
        }
        if (endTime != null) {
            wrapper.le(OperationLog::getOperationTime, endTime);
        }
        
        // 按操作时间倒序排序
        wrapper.orderByDesc(OperationLog::getOperationTime);
        
        Page<OperationLog> logPage = page(page, wrapper);

        // 填充用户名
        if (!logPage.getRecords().isEmpty()) {
            List<Long> userIds = logPage.getRecords().stream()
                    .map(OperationLog::getUserId)
                    .distinct()
                    .collect(Collectors.toList());
            
            Map<Long, String> userNames = userService.listByIds(userIds).stream()
                    .collect(Collectors.toMap(User::getId, User::getRealName));

            logPage.getRecords().forEach(log -> {
                log.setUsername(userNames.get(log.getUserId()));
            });
        }

        return logPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createLog(OperationLog log) {
        // 设置操作时间
        log.setOperationTime(LocalDateTime.now());
        return save(log);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchCreateLogs(List<OperationLog> logs) {
        if (logs == null || logs.isEmpty()) {
            return false;
        }
        
        // 设置操作时间
        LocalDateTime now = LocalDateTime.now();
        logs.forEach(log -> log.setOperationTime(now));
        
        return saveBatch(logs);
    }

    @Override
    public List<OperationLog> getLogsByUserId(Long userId) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OperationLog::getUserId, userId)
               .orderByDesc(OperationLog::getOperationTime);
        return list(wrapper);
    }

    @Override
    public List<OperationLog> getLogsByOperationType(String operationType) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OperationLog::getOperationType, operationType)
               .orderByDesc(OperationLog::getOperationTime);
        return list(wrapper);
    }

    @Override
    public List<OperationLog> getLogsByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(OperationLog::getOperationTime, startTime)
               .le(OperationLog::getOperationTime, endTime)
               .orderByDesc(OperationLog::getOperationTime);
        return list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cleanLogsBefore(LocalDateTime time) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(OperationLog::getOperationTime, time);
        return remove(wrapper);
    }
} 